/**************************************************************************//**
 * @file           main.c
 * @version        V1.0
 * $Revision:      1 $
 * $Date:          2017/01/04 $
 * @brief          Main function
 * @Author         Jeffrey Kang
 * @ContactInfo    chkang@esmt.com.tw
 *
 * @note
 *
 * Copyright (C) 1998 Elite Semiconductor Memory Technology Corp.
 * All rights reserved.
 *
 ******************************************************************************/


#include <REG52.h>
#include "system_FE81001.h"

 unsigned char xdata rx_buf[3]={0};
 
void I2C_Slave_Config();

/**
 * @brief       delay function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void delay (void)
{
	unsigned int i;
	
	for( i = 0 ; i < 200 ; i++ ){}
}


/**
 * @brief       I2CSISR function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
const void I2CISR (void) interrupt ISR_I2C
{
	unsigned char  dir;

	/* addr hit : check direction */
if ((I2C->int_st[0] & 0x08) == 0x08)
{
		I2C->int_st[0] = 0x08;
		
		dir = I2C->i2c_ctrl & 0x01;
		
		if (dir == 0) // Slave Read  ****	(dir == 0)	When master write  will run this section	****
			{		
          	while((I2C->int_st[1] & 0x01) != 0x01){} 
          	I2C->int_st[1] |= 0x01;	
          	rx_buf[0] = I2C->i2c_dat; //	Receive 1st data
          	
          	while((I2C->int_st[1] & 0x01) != 0x01){} 
          	I2C->int_st[1] |= 0x01;	
          	rx_buf[1] = I2C->i2c_dat; //	Receive 2st data
          			
          	while((I2C->int_st[1] & 0x01) != 0x01){} 
          	I2C->int_st[1] |= 0x01;
            rx_buf[2] = I2C->i2c_dat;	//	Receive 3st data		
          		
          	I2C->i2c_cmd = 0x05;
          	I2C_Slave_Config();  			
				}
				
		else	// Slave Write   ****  (dir == 1)  When master read will run this section	,  slave will	transfer data that master write **** 
			{
           	 I2C->i2c_dat = rx_buf[0]; //  Transfer 1st data
             while((I2C->int_st[0] & 0x80) != 0x80){} 
             I2C->int_st[0] |= 0x80;	
           	I2C->int_st[1] = 0x02;
           	I2C->i2c_dat = rx_buf[1]; //  Transfer 2st data
							 
           	while((I2C->int_st[0] & 0x80) != 0x80){} 
             I2C->int_st[0] |= 0x80;
           	I2C->int_st[1] = 0x02;
           	I2C->i2c_dat = rx_buf[2]; // Transfer 3st data
							
           	while((I2C->int_st[0] & 0x80) != 0x80){} 
           	I2C->int_st[0] |= 0x80;
           	I2C->int_st[1] = 0x02;
         
           	I2C->i2c_cmd = 0x05;
           	I2C_Slave_Config();
	   }
		
	}
	
	/* byte transmit */
	if ((I2C->int_st[0] & 0x80) == 0x80){
		I2C->int_st[0] = 0x80;
		I2C->int_st[1] = 0x02;
	}
	
	/* Cmpl */
	if ((I2C->int_st[1] & 0x02) == 0x02){
		I2C->int_st[1] = 0x02;
		I2C->int_st[0] = 0x80;
	}
	
	/* enable global interrupt */
	INTC->int_gmask = 0x01;
}



/**
 * @brief       IOConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void IOConfig()
{
	/* enable PA.4, PA.5 open drain */
	PORT_SetPAOpenDrain(BIT4 | BIT5);
	
	/* enable PA.4(SCL), PA.5(SDA) function */
	Set_PA4_SDA();
	Set_PA5_SCL();	
	
}


/**
 * @brief       CLKConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void CLKConfig()
{
	/* enable GPIO clock */
	PORT_PAPBPCPD_Clock_Enable();
	
	/* enable I2C clock */
	En_I2C_clk();
	
}

void I2C_Slave_Config()
{
	
		/* set slave address */
	I2C->slv_adr[0] = 0x48;
	I2C->slv_adr[1] = 0x00;
	
  	/* i2c setup */
	I2C->i2c_setup[0] = 0x01;         // Master = 0, Addressing = 0, IICEN = 1
	
	/* timing setup for I2C 400KHz of PCLK 8MHz */
	I2C_speed_400k_8M();
	
	/* interrupt enable */
	I2C->int_en[0] = 0x88;            // ByteTrans = 1, Start = 0, Stop = 0, ArbLose = 0, AddrHit = 1, FIFOHalf = 0, FIFOFull = 0, FIFOEmpty = 0
	I2C->int_en[1] = 0x10;            // Cmpl = 0, ByteRecv = 1
	
}


/**
 * @brief       main function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
int main (void)
{	
	CLKConfig();
	IOConfig();
	I2C_Slave_Config();
	
	/* enable global interrupt */
	INTC->int_gmask = 0x01;
	
	delay();
	
	while(1);
}

